import * as THREE from "three";
import * as d3 from "d3";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { LightProbeGenerator } from 'three/examples/jsm/lights/LightProbeGenerator.js';

// 导入贴图
import px from './textures/cube/px.png';
import py from './textures/cube/py.png';
import pz from './textures/cube/pz.png';
import nx from './textures/cube/nx.png';
import ny from './textures/cube/ny.png';
import nz from './textures/cube/nz.png';

// 墨卡托投影转换
const projection = d3.geoMercator().center([104.0, 37.5]).scale(80).translate([0, 0]);

// 定义材质颜色
const COLOR_ARR = ['#0465BD'];
const HIGHT_COLOR = '#4fa5ff';

export default class lineMap {
    constructor(container) {
        this.container = container;
        this.width = this.container.offsetWidth;
        this.height = this.container.offsetHeight;
        this.activeInstersect = []; // 存储当前选中的省份
    }

    init() {
        // 创建渲染器
        this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        this.renderer.setSize(this.width, this.height);
        this.container.appendChild(this.renderer.domElement);

        // 创建场景
        this.scene = new THREE.Scene();
        this.scene.background = null;

        // 创建相机
        this.camera = new THREE.PerspectiveCamera(45, this.width / this.height, 0.1, 1000);
        this.camera.position.set(0, -90, 70);
        this.camera.lookAt(0, 0, 0);

        // 添加光照
        this.setLight();

        // 添加控制器
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);

        // 设置射线拾取
        this.setRaycaster();

        // 加载地图数据
        const jsonData = require('./json/china.json');
        this.initMap(jsonData);

        // 动画循环
        this.animate();

        this.createStarField();
    }

    // 在init方法中添加：
    createStarField() {
        const vertices = [];
        for (let i = 0; i < 10000; i++) {
            const x = THREE.MathUtils.randFloatSpread(2000);
            const y = THREE.MathUtils.randFloatSpread(2000);
            const z = THREE.MathUtils.randFloatSpread(2000);
            vertices.push(x, y, z);
        }
        
        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
        
        const material = new THREE.PointsMaterial({
            size: 0.7,
            color: 0xFFFFFF,
            blending: THREE.AdditiveBlending,
            transparent: true
        });
        
        this.starField = new THREE.Points(geometry, material);
        this.scene.add(this.starField);
    }


    setLight() {
        // 环境光
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        this.scene.add(ambientLight);

        // 平行光
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.set(20, -50, 20);
        this.scene.add(directionalLight);

        // 点光源
        const pointLight = new THREE.PointLight(0xffffff, 0.5);
        pointLight.position.set(20, -50, 50);
        this.scene.add(pointLight);

        // 半球光
        const hemiLight = new THREE.HemisphereLight('#80edff', '#75baff', 0.3);
        hemiLight.position.set(20, -50, 0);
        this.scene.add(hemiLight);
    }

    setRaycaster() {
        this.raycaster = new THREE.Raycaster();
        this.mouse = new THREE.Vector2();
        this.isFirstMouseMove = true; // 添加标志位

        const onMouseMove = (event) => {
            // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
            const { top, left, width, height } = this.container.getBoundingClientRect();
            const clientX = event.clientX - left;
            const clientY = event.clientY - top;
            
            this.mouse.x = (clientX / width) * 2 - 1;
            this.mouse.y = -(clientY / height) * 2 + 1;
            
            // 第一次鼠标移动时设置标志位
            if (this.isFirstMouseMove) {
                this.isFirstMouseMove = false;
            }
        };

        window.addEventListener('mousemove', onMouseMove, false);
    }

    initMap(chinaJson) {
        // 建一个空对象存放对象
        this.map = new THREE.Object3D();

        let _this = this;

        // 加载贴图材质
        const urls = [px, nx, py, ny, pz, nz];

        // 绘制地图
        new THREE.CubeTextureLoader().load(urls, function(cubeTexture) {
            _this.lightProbe = new THREE.LightProbe();
            _this.lightProbe.copy(LightProbeGenerator.fromCubeTexture(cubeTexture));

            chinaJson.features.forEach((elem, index) => {
                // 定一个省份3D对象
                const province = new THREE.Object3D();
                // 每个的 坐标 数组
                const coordinates = elem.geometry.coordinates;
                const color = COLOR_ARR[index % COLOR_ARR.length];
                // 循环坐标数组
                coordinates.forEach(multiPolygon => {
                    multiPolygon.forEach((polygon) => {
                        const shape = new THREE.Shape();
                        
                        for (let i = 0; i < polygon.length; i++) {
                            let [x, y] = projection(polygon[i]);
                            
                            if (i === 0) {
                                shape.moveTo(x, -y);
                            }
                            shape.lineTo(x, -y);
                        }

                        const extrudeSettings = {
                            depth: 2,           // 增加深度
                            bevelEnabled: true, // 启用斜角
                            bevelThickness: 0.3,// 斜角厚度
                            bevelSize: 0.3,     // 斜角大小
                            bevelSegments: 5    // 斜角分段
                        };

                        const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
                        
                        // 修改initMap中的材质：（全图初始化的色块）
                        const material = new THREE.MeshStandardMaterial({
                            color: 0x4A3B8A, // 深紫色基底
                            metalness: 0.9,
                            roughness: 0.2,
                            emissive: 0x1A1F3D, // 微弱的自发光
                            emissiveIntensity: 0.3,
                            envMapIntensity: 1.0
                        });

                        const material1 = new THREE.MeshStandardMaterial({
                            color: 0x5E4AE3, // 亮紫色边缘(地图边缘颜色)
                            metalness: 0.95,
                            roughness: 0.1,
                            emissive: 0x2A3F5F,
                            emissiveIntensity: 0.5,
                            envMapIntensity: 1.0
                        });

                        const mesh = new THREE.Mesh(geometry, [
                            material,
                            material1
                        ]);
                        
                        mesh.castShadow = true;
                        mesh.receiveShadow = true;
                        mesh._color = color;
                        province.add(mesh);

                        // 创建边界线几何体
                        const edges = new THREE.EdgesGeometry(geometry);
                        
                        // 创建渐变色材质
                        const lineMaterial = new THREE.ShaderMaterial({
                            uniforms: {
                                color1: { value: new THREE.Color(0x80edff) }, // 浅蓝色
                                color2: { value: new THREE.Color(0x4A3B8A) }, // 深紫色
                                time: { value: 0 },
                                opacity: { value: 0.5 } // 添加透明度控制
                            },
                            vertexShader: `
                                varying vec2 vUv;
                                varying vec3 vPosition;
                                void main() {
                                    vUv = uv;
                                    vPosition = position;
                                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                                }
                            `,
                            fragmentShader: `
                                uniform vec3 color1;
                                uniform vec3 color2;
                                uniform float time;
                                uniform float opacity;
                                varying vec2 vUv;
                                varying vec3 vPosition;
                                void main() {
                                    // 使用y坐标和time来创建上下流动效果
                                    float flow = sin(vPosition.y * 0.1 + time * 2.0) * 0.5 + 0.5;
                                    // 添加一个额外的sin波来创建更复杂的流动效果
                                    float flow2 = sin(vPosition.y * 0.1 - time * 2.0) * 0.5 + 0.5;
                                    // 混合两个流动效果
                                    float finalFlow = (flow + flow2) * 0.5;
                                    vec3 color = mix(color1, color2, finalFlow);
                                    gl_FragColor = vec4(color, opacity);
                                }
                            `,
                            transparent: true,
                            side: THREE.DoubleSide
                        });

                        const line = new THREE.LineSegments(edges, lineMaterial);
                        // 根据是否是省份边界设置不同的缩放和透明度
                        if (elem.properties.name === 'China') {
                            line.scale.set(1.02, 1.02, 1.02); // 国家边界稍微大一点
                            lineMaterial.uniforms.opacity.value = 0.3; // 国家边界更透明
                        } else {
                            line.scale.set(1.01, 1.01, 1.01); // 省份边界
                            lineMaterial.uniforms.opacity.value = 0.7; // 省份边界更明显
                        }
                        province.add(line);
                    });
                });

                // 将geo的属性放到省份模型中
                province.properties = elem.properties;
                if (elem.properties.centorid) {
                    const [x, y] = projection(elem.properties.centorid);
                    province.properties._centroid = [x, y];
                }

                _this.map.add(province);
            });

            _this.scene.environment = cubeTexture;
            // 销毁贴图
            cubeTexture.dispose();
            _this.scene.add(_this.map);
            // 延迟2秒后启动自动高亮
            setTimeout(() => {
                setInterval(() => {
                    _this.startAutoHighlight();
                }, 2000);
            }, 2000);
        }, () => {}, (e) => {
            console.log(e);
        });
    }

    animate() {
        requestAnimationFrame(this.animate.bind(this));

        // 更新边界线的渐变动画
        this.map.traverse((child) => {
            if (child instanceof THREE.LineSegments) {
                child.material.uniforms.time.value += 0.01;
            }
        });

        // 更新射线拾取
        if (this.raycaster && !this.isFirstMouseMove) { // 只有在鼠标移动后才启用射线检测
            this.raycaster.setFromCamera(this.mouse, this.camera);
            
            // 计算物体和射线的焦点
            const intersects = this.raycaster.intersectObjects(this.map.children, true);

            // 恢复之前高亮的省份
            if (this.activeInstersect && this.activeInstersect.length > 0) {
                this.activeInstersect.forEach(element => {
                    const { object } = element;
                    if (Array.isArray(object.material)) {
                        object.material[0].color.set(0x4A3B8A);
                        object.material[1].color.set(0x5E4AE3);
                        object.scale.z = 1;
                    } else {
                        object.material.color.set(object._color);
                        object.scale.z = 1;
                    }
                });
            }

            this.activeInstersect = [];

            // 高亮当前选中的省份
            for (let i = 0; i < intersects.length; i++) {
                const intersect = intersects[i];
                // 跳过边界线对象
                if (intersect.object instanceof THREE.LineSegments) continue;
                
                if (intersect.object.material) {
                    this.activeInstersect.push(intersect);
                    if (Array.isArray(intersect.object.material)) {
                        intersect.object.material[0].color.set(0x5E4AE3);
                        intersect.object.material[1].color.set(0x80edff);
                    } else {
                        intersect.object.material.color.set(HIGHT_COLOR);
                    }
                    // 设置高度动画
                    intersect.object.scale.z = 2.0; // 增加高亮时的高度
                    break;
                }
            }
        }

        this.controls.update();
        this.renderer.render(this.scene, this.camera);
    }

    resize() {
        this.width = this.container.offsetWidth;
        this.height = this.container.offsetHeight;
        this.camera.aspect = this.width / this.height;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(this.width, this.height);
    }

    destroy() {
        if (this.renderer) {
            this.renderer.dispose();
            this.renderer.domElement = null;
            this.renderer = null;
        }
        window.removeEventListener('resize', this.resize.bind(this));
    }

    startAutoHighlight() {
        if (this.map && this.map.children.length > 0) {
            // 如果当前有高亮的省份，先恢复原状
            if (this.currentHighlightedProvince) {
                this.currentHighlightedProvince.children.forEach(mesh => {
                    // 跳过边界线对象
                    if (mesh instanceof THREE.LineSegments) return;
                    
                    // 只有当省份不是鼠标悬停的省份时才恢复
                    if (!this.activeInstersect.some(intersect => intersect.object === mesh)) {
                        mesh.material[0].color.set(0x4A3B8A); // 恢复为深紫色基底
                        mesh.material[1].color.set(0x5E4AE3); // 恢复为亮紫色边缘
                        mesh.scale.z = 1;
                    }
                });
            }

            // 随机选择一个新省份
            const randomIndex = Math.floor(Math.random() * this.map.children.length);
            const newProvince = this.map.children[randomIndex];
            
            // 高亮新选择的省份
            newProvince.children.forEach(mesh => {
                // 跳过边界线对象
                if (mesh instanceof THREE.LineSegments) return;
                
                // 只有当省份不是鼠标悬停的省份时才高亮
                if (!this.activeInstersect.some(intersect => intersect.object === mesh)) {
                    mesh.material[0].color.set(0x5E4AE3); // 高亮时的基底颜色
                    mesh.material[1].color.set(0x80edff); // 高亮时的边缘颜色
                    mesh.scale.z = 1.5;
                }
            });

            this.currentHighlightedProvince = newProvince;
        }
    }
}